#pragma once
#pragma warning (disable : 4661)
#include "predef.h"

/*
	four step to make your class singleton:

		1.derive your class from Pattern::Singleton,pass your class name to 'T'

		2.prepare a 0 parameter constructor for your class and make sure it is the only constructor available.

		3.make sure your constructor is private,and place DECLARE_Singleton into your class declaration
			(parameter 'T' receives your class name)

		4.place USE_Singleton into your cpp after your includes and before your implementations
			(parameter 'T' receives your class name,but make it fully-qualified here if you`re not using your namespace)


	after these,you can access to the singleton instance of your class by invoking YourClass::getInstancePtr().

	A class to be singleton should never be constructed by other codes,so it can only have one private constructor for base Singleton.
	this is all i need to make your class really singleton,so do not break this rule until i found a better way.
	this Singleton uses mutex to ensure there`s only one instance to be constructed,but there`s no futher consider for multithread safety.

							by Z7 at 2009.04.04

							DO NOT REMOVE THIS NOTICE.
*/

namespace Pattern
{
	template<typename T>
	class Singleton
	{
	protected:
		static T * instance;	
		static boost::mutex instanceMutex;
	public:
		static T * getInstancePtr()
		{			
			instanceMutex.lock();			
			if(instance == 0)instance = new T();
			instanceMutex.unlock();	

			return instance;
		}
		
		static T & getInstanceRef()
		{
			return *getInstancePtr();
		}

		static void destoryInstance()
		{
			if(instance==0)return;
			instanceMutex.lock();			
			delete instance;
			instance = 0;
			instanceMutex.unlock();			
		}
	};
}


#define IMPLEMENT_Singleton(T)\
	T * Pattern::Singleton<T> :: instance = 0;\
	boost::mutex Pattern::Singleton<T>::instanceMutex;

#define DECLARE_Singleton(T)\
	friend class Pattern::Singleton<T>;